package com.mjfeed.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.mjfeed.Principal;
import com.mjfeed.dao.CartDao;
import com.mjfeed.dto.api.CartItemJSON;
import com.mjfeed.dto.api.CartItemListJSON;
import com.mjfeed.entity.Cart;
import com.mjfeed.entity.CartItem;
import com.mjfeed.entity.Member;
import com.mjfeed.entity.Product;
import com.mjfeed.service.CartService;
import com.mjfeed.util.Md5Util;
import com.mjfeed.util.WebUtils;

@Service("cartService")
public class CartServiceImpl extends BaseServiceImpl implements CartService {
	@Resource(name="cartDao")
	private CartDao cartDao;

	@Transactional
	public Cart getCurrent() {
		RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes();
		if (requestAttributes != null) {
			HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
			Principal principal = (Principal) request.getSession().getAttribute(Member.PRINCIPAL_ATTRIBUTE_NAME);
			Member member = principal != null ? getById(Member.class, principal.getId()) : null;
			if (member != null) {
				Cart cart = member.getCart();
				if (cart != null) {
					if (!cart.hasExpired()) {
						if (!DateUtils.isSameDay(cart.getModifyDate(), new Date())) {
							cart.setModifyDate(new Date());
							cartDao.update(cart);
						}
						return cart;
					} else {
						delete(cart);
					}
				}
			} else {
				String id = WebUtils.getCookie(request, Cart.ID_COOKIE_NAME);
				String key = WebUtils.getCookie(request, Cart.KEY_COOKIE_NAME);
				if (StringUtils.isNotEmpty(id) && StringUtils.isNumeric(id) && StringUtils.isNotEmpty(key)) {
					Cart cart = getById(Cart.class, Long.valueOf(id));
					if (cart != null && cart.getMember() == null && StringUtils.equals(cart.getKey(), key)) {
						if (!cart.hasExpired()) {
							if (!DateUtils.isSameDay(cart.getModifyDate(), new Date())) {
								cart.setModifyDate(new Date());
								cartDao.update(cart);
							}
							return cart;
						} else {
							delete(cart);
						}
					}
				}
			}
		}
		return null;
	}

	@Transactional
	public void merge(Member member, Cart cart) {
		if (member != null && cart != null && cart.getMember() == null) {
			Cart memberCart = member.getCart();
			if (memberCart != null) {
				for (Iterator<CartItem> iterator = cart.getCartItems().iterator(); iterator.hasNext();) {
					CartItem cartItem = iterator.next();
					Product product = cartItem.getProduct();
					if (memberCart.contains(product)) {
						if (Cart.MAX_PRODUCT_COUNT != null && memberCart.getCartItems().size() > Cart.MAX_PRODUCT_COUNT) {
							continue;
						}
						CartItem item = memberCart.getCartItem(product);
						item.add(cartItem.getQuantity());
						cartDao.update(item);
					} else {
						if (Cart.MAX_PRODUCT_COUNT != null && memberCart.getCartItems().size() >= Cart.MAX_PRODUCT_COUNT) {
							continue;
						}
						iterator.remove();
						cartItem.setCart(memberCart);
						memberCart.getCartItems().add(cartItem);
						cartDao.update(cartItem);
					}
				}
				delete(cart);
			} else {
				member.setCart(cart);
				cart.setMember(member);
				cartDao.update(cart);
			}
		}
	}

	public void evictExpired() {
	}

	@Transactional
	public Set<CartItem> sync(Member member, String cartData) {
		if (cartData != null && !cartData.equals("")) {
			Cart cart = member.getCart();
			if (cart == null) {
				cart = new Cart();
				cart.setKey(Md5Util.encrypt(RandomStringUtils.randomAlphabetic(30)));
				cart.setMember(member);
				save(cart);
			}
			String[] cartArray = cartData.split(",");
			for (String string : cartArray) {
				String[] cartItemArray = string.split("!");
				Long productId = Long.valueOf(cartItemArray[0]);
				Integer quantity = Integer.valueOf(cartItemArray[1]);
				Product product = getById(Product.class, productId);
				if (product == null) continue;
				// TODO 如果要准确可以加上 数量判断
				if (cart.contains(product)) {
					CartItem cartItem = cart.getCartItem(product);
					if (cartItem.getQuantity().intValue() == quantity.intValue()) { //app欢迎页面同步时同个商品数量相同不累加
						continue;
					}
					if (product.getStock() != null && quantity > product.getStock()) {
						continue;
					}
					cartItem.setQuantity(quantity);
					update(cartItem);
				} else {
					if (product.getStock() != null && quantity > product.getStock()) {
						continue;
					}
					CartItem cartItem = new CartItem();
					cartItem.setQuantity(quantity);
					cartItem.setProduct(product);
					cartItem.setCart(cart);
					save(cartItem);
					cart.getCartItems().add(cartItem);
					update(cart);
				}
			}
		}
		
		Cart cart = member.getCart();
		if (cart != null) {
			return cart.getCartItems();
		}
		return null;
	}

	@Override
	public CartItemListJSON searchToJSON(Set<CartItem> cartItems) {
		if (cartItems != null && cartItems.size() > 0) {
			CartItemListJSON cartItemListJSON = new CartItemListJSON();
			List<CartItemJSON> recordList = new ArrayList<CartItemJSON>();
			for (CartItem cartItem : cartItems) {
				CartItemJSON cartItemJSON = new CartItemJSON();
				cartItemJSON.setCartItemId(cartItem.getId());
				cartItemJSON.setCartId(cartItem.getCart().getId());
				cartItemJSON.setProductId(cartItem.getProduct().getId());
				cartItemJSON.setQuantity(cartItem.getQuantity());
				cartItemJSON.setSn(cartItem.getProduct().getSn());
				cartItemJSON.setName(cartItem.getProduct().getName());
				cartItemJSON.setPrice(cartItem.getPrice());
				cartItemJSON.setStock(cartItem.getProduct().getStock());
				cartItemJSON.setImageUrl("http://192.168.1.101/skin/images/pro1.jpg");
				recordList.add(cartItemJSON);
			}
			cartItemListJSON.setRecordList(recordList);
			return cartItemListJSON;
		}
		return null;
	}

	@Transactional
	public void update(Member member, String cartItemData) {
		if (cartItemData != null) {
			String[] cartItemArray = cartItemData.split("!");
			Long cartItemId = Long.valueOf(cartItemArray[0]);
			Long productId = Long.valueOf(cartItemArray[1]);
			Integer quantity = Integer.valueOf(cartItemArray[2]);
			CartItem cartItem = getById(CartItem.class, cartItemId);
			if (cartItem != null) {
				if (cartItem.getProduct().getId().equals(productId)) {
					cartItem.setQuantity(quantity);
				}
				update(cartItem);
			}
		}
	}
	
	@Transactional
	public void delete(Member member, String cartItemData) {
		if (cartItemData != null) {
			String[] cartItemArray = cartItemData.split("!");
			Long cartItemId = Long.valueOf(cartItemArray[0]);
			Long productId = Long.valueOf(cartItemArray[1]);
//			Integer quantity = Integer.valueOf(cartItemArray[2]);
			CartItem cartItem = getById(CartItem.class, cartItemId);
			if (cartItem != null) {
				if (cartItem.getProduct().getId().equals(productId)) {
					delete(cartItem);
				}
			}
		}
	}
}
